--- title: Capture keywords: fastai sidebar: home_sidebar summary: "Wrapper class and example code for getting images from the OpenHSI using a ximea detetor (with IMX252 sensor, e.g. MX031CG-SY. " description: "Wrapper class and example code for getting images from the OpenHSI using a ximea detetor (with IMX252 sensor, e.g. MX031CG-SY. " nb_path: "01_capture.ipynb" ---
{% raw %}
/Users/eway/.pyenv/versions/3.8.3/lib/python3.8/site-packages/pandas/compat/__init__.py:97: UserWarning: Could not import the lzma module. Your installed Python is incomplete. Attempting to use lzma compression will result in a RuntimeError.
  warnings.warn(msg)
{% endraw %} {% raw %}
{% endraw %} {% raw %}
{% endraw %} {% raw %}

class OpenHSI[source]

OpenHSI(n_lines:int=16, processing_lvl:int=2, txt_path:str='assets/cam_settings.txt', pkl_path:str='assets/cam_calibration.pkl') :: DataCube

Base Class for the OpenHSI Camera.

{% endraw %} {% raw %}
{% endraw %}

Running in notebook slow downs.

{% raw %}

OpenHSI.collect[source]

OpenHSI.collect()

Collect the hyperspectral datacube.

{% endraw %}

To add a custom camera, four methods need to be defined in a class to:

  1. Initialise camera __init__,
  2. Open camera start_cam,
  3. Close camera stop_cam, and
  4. Capture a picture as a numpy array get_img.

By inheriting from the OpenHSI class, all the methods to load settings/calibration files, collect datacube, saving data to NetCDF, and viewing as RGB are integrated. Furthermore, the custom camera class can be passed to a SettingsBuilder class for calibration.

{% raw %}

class SimulatedCamera[source]

SimulatedCamera(img_path:str=None, n_lines:int=16, processing_lvl:int=2, txt_path:str='assets/cam_settings.txt', pkl_path:str='assets/cam_calibration.pkl') :: OpenHSI

Add

{% endraw %} {% raw %}
100%|██████████| 1024/1024 [00:16<00:00, 62.55it/s]
{% endraw %} {% raw %}
with SimulatedCamera(img_path="assets/rocky_beach.png", n_lines=128, processing_lvl = 3) as cam:
    cam.collect()
    fig = cam.show(hist_eq=True)
    
fig
100%|██████████| 128/128 [00:04<00:00, 28.30it/s]
{% endraw %} {% raw %}
plt.imshow(cam.rgb_buff.data)
<matplotlib.image.AxesImage at 0x12c404ee0>
{% endraw %} {% raw %}
plt.plot(cam.λs,cam.xs[0],'r',label="X(λ)")
plt.plot(cam.λs,cam.ys[0],'g',label="Y(λ)")
plt.plot(cam.λs,cam.zs[0],'b',label="Z(λ)")
plt.grid(); plt.minorticks_on()
plt.legend()
plt.xlabel("λ (nm)")
plt.ylabel("CIE XYZ value")
Text(0, 0.5, 'CIE XYZ value')
{% endraw %} {% raw %}
plt.plot(cam.binned_wavelengths,cam.dc.data[350,300,:],label="rock")
plt.plot(cam.binned_wavelengths,cam.dc.data[50,300,:], label="sky")
plt.plot(cam.binned_wavelengths,cam.dc.data[150,300,:],label="water")
plt.legend()
plt.xlabel("wavelength (nm)")
plt.ylabel("pseudo-spectra")
Text(0, 0.5, 'pseudo-spectra')
{% endraw %}

XIMEA Camera

Used for the OpenHSI Camera Mark I.

Make sure you install the Ximea API beforehand in the instructions https://www.ximea.com/support/wiki/apis/Python

{% raw %}
@delegates()
class XimeaCamera(OpenHSI):
    try:
        from ximea import xiapi
        xicam = xiapi.Camera()
    except ModuleNotFoundError:
        warnings.warn("ModuleNotFoundError: No module named 'ximea'.",stacklevel=2)
        
    """Core functionality for Ximea cameras"""
    # https://www.ximea.com/support/wiki/apis/Python
    def __init__(self, xbinwidth:int = 896, xbinoffset:int = 528, exposure_ms:float = 10, serial_num:str = None, **kwargs):
        """Initialise Camera"""
        
        super().__init__(**kwargs)  
        
        self.xicam.open_device_by_SN(serial_num) if serial_num else self.xicam.open_device()

        print(f'Connected to device {self.xicam.get_device_sn()}')

        self.xbinwidth  = xbinwidth
        self.xbinoffset = xbinoffset
        self.exposure   = exposure_ms
        self.gain       = 0

        self.xicam.set_width(self.xbinwidth)
        self.xicam.set_offsetX(self.xbinoffset)
        self.xicam.set_exposure_direct(1000*self.exposure)
        self.xicam.set_gain_direct(self.gain)

        self.xicam.set_imgdataformat("XI_RAW16")
        self.xicam.set_output_bit_depth("XI_BPP_12")
        self.xicam.enable_output_bit_packing()
        self.xicam.disable_aeag()
        
        self.xicam.set_binning_vertical(2)
        self.xicam.set_binning_vertical_mode("XI_BIN_MODE_SUM")

        self.rows, self.cols = self.xicam.get_height(), self.xicam.get_width()
        self.img = xiapi.Image()
        
        self.load_cam_settings()
    
    def start_cam(self):
        self.xicam.start_acquisition()
    
    def stop_cam(self):
        self.xicam.stop_acquisition()
        self.xicam.close_device()
    
    def get_img(self) -> np.ndarray:
        self.xicam.get_image(self.img)
        return self.img.get_image_data_numpy()
{% endraw %} {% raw %}
with XimeaCamera(n_lines=1024, processing_lvl = 3) as cam:
    cam.collect()
    fig = cam.show(robust=True)
    
fig
---------------------------------------------------------------------------
Xi_error                                  Traceback (most recent call last)
<ipython-input-384-79ae81ab2b5b> in <module>
      1 #hardware
      2 
----> 3 with XimeaCamera(n_lines=1024, processing_lvl = 3) as cam:
      4     cam.collect()
      5     fig = cam.show(robust=True)

<ipython-input-383-8a38acd22f4f> in __init__(self, xbinwidth, xbinoffset, exposure_ms, serial_num, **kwargs)
     16         super().__init__(**kwargs)
     17 
---> 18         self.xicam.open_device_by_SN(serial_num) if serial_num else self.xicam.open_device()
     19 
     20         print(f'Connected to device {self.xicam.get_device_sn()}')

~/.pyenv/versions/3.8.3/lib/python3.8/site-packages/ximea/xiapi.py in open_device(self)
    207             stat = self.device.xiOpenDevice(self.dev_id, byref(self.handle))
    208             if not stat == 0:
--> 209                 raise Xi_error(stat)
    210 
    211             self.CAM_OPEN = True

Xi_error: ERROR 56: No Devices Found
{% endraw %}